package com.jiepos.mpos.pay;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.betterda.paycloud.sdk.util.Base64Util;
import com.betterda.paycloud.sdk.util.KeyGenerator;
import com.epayplusplus.api.EpayppEncrypt;
import com.epayplusplus.api.EpayppSignature;
import com.epayplusplus.api.enums.EncryptTypeEnum;
import com.epayplusplus.api.enums.SignMethodEnum;
import com.hy.pmp.bo.DataMessage;
import com.hy.utils.JsonUtil;
import com.hy.utils.RSAUtils;
import com.jiepos.mpos.common.constant.SystemConstant;
import com.jiepos.mpos.common.entity.GpsEntity;
import com.jiepos.mpos.core.service.BaseInterService;
import com.jiepos.mpos.core.util.DateUtil;
import com.jiepos.mpos.core.util.GlobalUtils;
import com.jiepos.mpos.core.util.MathUtils;
import com.jiepos.mpos.core.util.StringUtils;
import com.jiepos.mpos.inter.intopieces.dto.ResponseDTO;
import com.jiepos.mpos.pay.quickpay.service.IQuickPayService;
import com.jiepos.mpos.pay.quickpay.service.yeepay.Digest;


/**
 * 
 * <p>标题: —— 支付请求及回调请求数据</p>
 * <p>模块: 通用平台</p>
 * <p>版权: Copyright (c) 2017 江苏杰博实信息技术有限公司
 * @author 娄伟峰
 * @version 1.0
 * @since 2017年9月13日 下午2:06:59
 * @history（历次修订内容、修订人、修订时间等）
 */
@Controller
@RequestMapping("httppay")
@SuppressWarnings("rawtypes")
public class PayController {
	public static final Logger _log = LoggerFactory.getLogger(PayController.class);

	@Autowired
	private PayService payService;
	
	@Autowired
	private AppLogTransJnlsPayService appLogTransJnlsPayService;
	
	@Autowired
	private MainBusinessService mainBusinessService;
	
	@Autowired
	private BaseInterService baseInterService;
		
		
	/**
	 * 
	 * 接口: 预下单控制层
	 * @param request 客户端请求
	 * @param response 响应
	 * @param gpsEntity 公共实体
	 * @param random_number 随机数
	 * @param service_no 业务编号
	 * @param param_no 参数编号
	 * @param custom_no 客户编号
	 * @param snd_dt 受卡方所在地日期
	 * @param snd_ts 受卡方所在地时间
	 * @param pay_mode 支付类型
	 * @param trans_at 交易金额
	 * @param login_id 登录login_id
	 * @return
	 * @author 杨剑武
	 * @since 2017年10月25日
	 */
	@RequestMapping("/preOrder.do")
	public @ResponseBody Map preOrder(HttpServletRequest request, HttpServletResponse response, GpsEntity gpsEntity,
			String random_number, String service_no, String param_no, String custom_no, String snd_dt, String snd_ts,
			String pay_mode, String trans_at, String login_id) {
		Thread.currentThread().setName(custom_no+"_");//标记当前交易处理线程名
		//验签数据拼接
		StringBuffer sb=new StringBuffer();
		sb.append(StringUtils.objToString(gpsEntity.getSerial_number())).append(StringUtils.objToString(random_number))
		.append(StringUtils.objToString(service_no)).append(StringUtils.objToString(param_no))
		.append(StringUtils.objToString(custom_no)).append(StringUtils.objToString(snd_dt))
		.append(StringUtils.objToString(snd_ts)).append(StringUtils.objToString(pay_mode))
		.append(StringUtils.objToString(trans_at));

		return payService.preOrder(request, gpsEntity, custom_no, trans_at, random_number,
				service_no, param_no, snd_dt, snd_ts, pay_mode, login_id, sb.toString(), null);

	}
	
	/**
	 * 接口: 快捷支付控制层
	 * @param gpsEntity	 
	 * @param random_number 客户端上送的随机数
	 * @param service_no 业务编号
	 * @param param_no 参数编号
	 * @param custom_no 客户编号
	 * @param snd_dt 受卡方所在地日期
	 * @param snd_ts 受卡方所在地时间
	 * @param order_no 订单号
	 * @param act_out_no 支付账号
	 * @param crd_exp 卡有效期
	 * @param phone 银行预留手机号
	 * @param cvv2 cvv2
	 * @param rand 验证码
	 * @param pin 密码
	 * @param trace_no 交易流水号 
	 * @param orderType 订单类型
	 * @return
	 */
	@RequestMapping("/quickPay.do")
	public @ResponseBody Map quickPay(HttpServletRequest request, HttpServletResponse response,GpsEntity gpsEntity,String random_number,String service_no,
			String param_no,String custom_no,String snd_dt,String snd_ts,String order_no,String act_out_no,String crd_exp,
			String phone,String cvv2,String rand,String pin,String trace_no,String orderType,String login_id,String bankcard_uuid){				
		Thread.currentThread().setName(custom_no + "_" + trace_no);//标记当前交易处理线程名
		//验签数据拼接	
		StringBuffer sb=new StringBuffer();
		sb.append(StringUtils.objToString(gpsEntity.getSerial_number())).append(StringUtils.objToString(random_number))
		.append(StringUtils.objToString(service_no)).append(StringUtils.objToString(param_no))
		.append(StringUtils.objToString(custom_no)).append(StringUtils.objToString(snd_dt))
		.append(StringUtils.objToString(snd_ts)).append(StringUtils.objToString(order_no))
		.append(StringUtils.objToString(act_out_no)).append(StringUtils.objToString(crd_exp))
		.append(StringUtils.objToString(phone)).append(StringUtils.objToString(cvv2))
		.append(StringUtils.objToString(rand)).append(StringUtils.objToString(pin))
		.append(StringUtils.objToString(trace_no)).append(StringUtils.objToString(orderType));

		return payService.payOrder(request,gpsEntity, random_number,service_no,
				param_no,custom_no,snd_dt,snd_ts,order_no,act_out_no,crd_exp,
				phone,cvv2,rand,pin,trace_no,orderType,login_id,bankcard_uuid,sb.toString(),null);					
	}
	
	/**
	 * 
	 * 接口: 手机验证码验证
	 * @param request
	 * @param response
	 * @param gpsEntity
	 * @param loc_trace_no
	 * @param phone
	 * @param verify_code
	 * @param pay_pass_word
	 * @return
	 * @since 2017年12月5日
	 */
	@RequestMapping("/verifyCode.do")
	public @ResponseBody Map verifyCode(HttpServletRequest request, HttpServletResponse response, GpsEntity gpsEntity,
			String random_number, String custom_no, String loc_trace_no, String phone, String verify_code,
			String pay_pass_word, String login_id) {
		StringBuilder builder = new StringBuilder().append(StringUtils.objToString(gpsEntity.getSerial_number()))
				.append(StringUtils.objToString(custom_no)).append(StringUtils.objToString(loc_trace_no))
				.append(StringUtils.objToString(phone)).append(StringUtils.objToString(verify_code))
				.append(StringUtils.objToString(pay_pass_word));
		return payService.verifyCode(request, response, gpsEntity, random_number, custom_no, loc_trace_no, phone,
				verify_code, pay_pass_word, login_id, builder.toString());
	}
	
	/**
	 * 
	 * @param gpsEntity	 
	 * @param random_number 客户端上送的随机数
	 * @param service_no 业务编号
	 * @param param_no 参数编号
	 * @param custom_no 客户编号
	 * @param snd_dt 受卡方所在地日期
	 * @param snd_ts 受卡方所在地时间
	 * @param order_no 订单号
	 * @param loc_trace_no 本地流水号
	 * @return
	 */
	@RequestMapping("/queryResult.do")
	public @ResponseBody Map queryResult(HttpServletRequest request, HttpServletResponse response,GpsEntity gpsEntity,String random_number,String service_no,
			String param_no,String custom_no,String snd_dt,String snd_ts,String order_no,String trace_no,String loc_trace_no,String login_id){				
		StringBuffer sb=new StringBuffer();
		sb.append(StringUtils.objToString(gpsEntity.getSerial_number())).append(StringUtils.objToString(random_number))
		.append(StringUtils.objToString(service_no)).append(StringUtils.objToString(param_no))
		.append(StringUtils.objToString(custom_no)).append(StringUtils.objToString(snd_dt))
		.append(StringUtils.objToString(snd_ts)).append(StringUtils.objToString(order_no))
		.append(StringUtils.objToString(loc_trace_no));														
		
		return payService.queryResult(request,gpsEntity,random_number, service_no, 
				param_no, custom_no, snd_dt, snd_ts, order_no,trace_no, loc_trace_no, login_id, sb.toString(),null);			
	}
	
	/**
	 * 
	 * @param gpsEntity	 
	 * @param random_number 客户端上送的随机数
	 * @param service_no 业务编号
	 * @param param_no 参数编号
	 * @param custom_no 客户编号
	 * @param snd_dt 受卡方所在地日期
	 * @param snd_ts 受卡方所在地时间
	 * @param trans_at 交易金额
	 * @param acc_type 账户类型
	 * @param cash_type 提现类型
	 * @param pay_password 支付密码
	 * @param rand 验证码
	 * @return
	 */
	@RequestMapping("/withdraw.do")
	public @ResponseBody Map withdraw(HttpServletRequest request, HttpServletResponse response,GpsEntity gpsEntity,String random_number,String service_no,
			String param_no,String custom_no,String snd_dt,String snd_ts,String trans_at,String acc_type,
			String pay_password,String rand,String login_id,String cash_fee){				
		
		StringBuffer sb=new StringBuffer();
		sb.append(StringUtils.objToString(gpsEntity.getSerial_number())).append(StringUtils.objToString(random_number))
		.append(StringUtils.objToString(service_no)).append(StringUtils.objToString(param_no))
		.append(StringUtils.objToString(custom_no)).append(StringUtils.objToString(snd_dt))
		.append(StringUtils.objToString(snd_ts)).append(StringUtils.objToString(trans_at))
		.append(StringUtils.objToString(acc_type)).append(StringUtils.objToString(pay_password))
		.append(StringUtils.objToString(rand));		
		
		return payService.withdraw(request,gpsEntity,random_number, service_no, param_no, custom_no, snd_dt, 
				snd_ts, trans_at, acc_type,pay_password,rand,login_id,cash_fee,sb.toString(), null);			
	}
	
	/**
	 * 
	 * @param gpsEntity	 
	 * @param random_number 客户端上送的随机数
	 * @param user_name App登录账号	 
	 * @param custom_no 客户编号
	 * @param snd_dt 受卡方所在地日期
	 * @param snd_ts 受卡方所在地时间	 
	 * @param custom_source 客户来源
	 * @param client_version 客户端版本
	 * @param session_id 登陆后的sessionid
	 * @return
	 */
	@RequestMapping("/getParamKey.do")
	public @ResponseBody Map getParamKey(HttpServletRequest request, HttpServletResponse response,GpsEntity gpsEntity,String random_number,
			String custom_no,String snd_dt,String snd_ts,String custom_source,String client_version,String login_id){																		
		
		StringBuffer sb=new StringBuffer();
		sb.append(StringUtils.objToString(gpsEntity.getSerial_number())).append(StringUtils.objToString(random_number))	
		.append(StringUtils.objToString(custom_no)).append(StringUtils.objToString(snd_dt))
		.append(StringUtils.objToString(snd_ts)).append(StringUtils.objToString(custom_source))
		.append(StringUtils.objToString(client_version));
				
		
		return payService.paramKey(request,gpsEntity,random_number, custom_no, snd_dt, 
				snd_ts, custom_source, client_version, login_id, sb.toString(),null);				
	}
	
	
	/**
	 * 来逗阵异步通知回调
	 * @param request
	 * @param response
	 * @throws Exception 
	 */
	@RequestMapping("/laiDouZhenNotice.do")
	public @ResponseBody String laiDouZhenNotice(HttpServletRequest request, HttpServletResponse response) {
		try{
	        String pubkey=GlobalUtils.getPayConfProperty("pay.ys.pubkey");
	        String data=request.getParameter("data");
	        String signature=request.getParameter("signature");     
	        _log.info("异步通知data:"+data+"&signature:"+signature);
	        if(StringUtils.isBlank(data)||StringUtils.isBlank(signature)){
	        	return "fail";// 回调失败
	        }
	        String loc_sig=new String(KeyGenerator.decryptByPublicKey(Base64Util.decode(data), pubkey));
	        //String loc_sig="{\"appId\":\"0b98b7ac468c4eeda9d8e17aa3ed5c9f\",\"channelType\":\"88\",\"merNoticeUrl\":\"https://139.196.226.55:18443/mpos/httppay/ysNotice.do\",\"orderId\":\"201710271104460014\",\"payStatus\":\"Y\",\"payTime\":\"20171027111134\",\"paymentType\":\"20\",\"platMerId\":\"快捷支付D+0测试商户\",\"queryId\":\"81217102615185411888\",\"remark\":\"success\",\"settleAmt\":\"1400\",\"settleDate\":\"20171027\",\"settleStatus\":\"Y\",\"tradeNo\":\"81217102615185411888\",\"txnAmt\":\"1500\",\"txnTime\":\"20171027111034\",\"version\":\"1.0.1\"}";
	        _log.info("异步通知解密后的数据:"+loc_sig);
	        boolean verifySig=KeyGenerator.verify(loc_sig.getBytes(), pubkey, signature);
	        if(verifySig){
	        	 Map<String, Object> reqMap = JSON.parseObject(loc_sig);
	        	 Map<String, String> paramMap = new HashMap<String, String>();
	        	 for(Map.Entry<String, Object> entry : reqMap.entrySet()){
	        		 paramMap.put(entry.getKey(), String.valueOf(entry.getValue()));           
	             }
	        	 String loc_trace_no=paramMap.get("orderId");
	        	 Map<String,String> transMap=appLogTransJnlsPayService.getTransJnlsByNo(null, loc_trace_no,null,null);
	             IQuickPayService iQuickPayService=CommonService.getPayServices().get(transMap.get("trf_channel_id"));
	             try{
	            	 boolean result=iQuickPayService.noticeOrder(paramMap); 
	            	 if(result){
	            		 _log.info("支付成功异步通知管理系统 loc_trace_no=" + paramMap.get("orderId"));
	         			try {
	         				mainBusinessService.asyncNotifyMpos(paramMap.get("orderId"));
	         			} catch (Exception e) {
	         				_log.info("支付成功异步通知管理系统失败");
	         			}
	         			
	         			ResponseDTO responseDto = new ResponseDTO();
	         			Map<String, String> dataMap = new HashMap<>();
	         			dataMap.put("order_no", transMap.get("order_no"));
	         			dataMap.put("channel_trace_no", loc_trace_no);
	         			dataMap.put("trans_at", paramMap.get("txnAmt"));
	         			dataMap.put("midfee", "");
	         			dataMap.put("costfee", "");
	         			dataMap.put("mchnt_cd", transMap.get("custom_no"));
	         			dataMap.put("pay_success_time", StringUtils.isBlank(paramMap.get("payTime"))?"":paramMap.get("payTime"));
	         			dataMap.put("trs_stat", CommonService.encapRespCode(paramMap.get("payStatus"), paramMap.get("errorCode")));// 交易状态
	         			dataMap.put("stl_st", CommonService.encapSettleRespCode(paramMap.get("settleStatus")));
	         	    	dataMap.put("stl_dt", paramMap.get("settleDate"));
	         	    	dataMap.put("stl_time", "");
	         	    	dataMap.put("stl_amt", paramMap.get("settleAmt"));
	         	    	String respData = baseInterService.getResponseBizContent(null, dataMap);
	         	    	responseDto.setData(respData);
	         			mainBusinessService.asyncNotifyDto(transMap.get("dto_bg_url"), loc_trace_no, transMap.get("loc_dt"), responseDto);
	         			
	            		return "success";// 回调成功                
	            	 }else{
	            		return "fail";// 回调失败
	            	 }            	 
	             }catch(Exception e){           	 
	            	 _log.error("异步通知更新发生异常",e);
	            	 return "fail";// 回调失败
	             }             
	        }else{
	        	return "fail";// 回调失败
	        }
		}
        catch(Exception e){           	 
       	 _log.error("异步通知更新发生异常",e);
       	 return "fail";// 回调失败
        }  
              
	}
	
	
	@RequestMapping("/laiDouZhenPageNotice.do")
	public ModelAndView laiDouZhenPageNotice(HttpServletRequest request, HttpServletResponse response) throws Exception{		
        Map<String, Object> paramMap = new HashMap<String, Object>();
        Map<String, String[]> requestMap = request.getParameterMap();
        Iterator<Entry<String, String[]>> it = requestMap.entrySet().iterator();
        while (it.hasNext()) {
            Entry<String, String[]> entry = it.next();
            if (entry.getValue().length == 1) {
                paramMap.put(entry.getKey(), entry.getValue()[0]);
            } else {
                String[] values = entry.getValue();
                String value = "";
                for (int i = 0; i < values.length; i++) {
                    value = values[i] + ",";
                }
                value = value.substring(0, value.length() - 1);
                paramMap.put(entry.getKey(), value);
            }
        }
        _log.info("前台异步通知参数=[{}]",paramMap);
        return new ModelAndView("redirect:/module/pay/laiDouZhenPage.html");
                               
	}
	
	/**
	 * 融商异步回调
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/ePayNotice.do")
	public @ResponseBody String ePayNotice(HttpServletRequest request, HttpServletResponse response) {
		try{			
			String publickey=GlobalUtils.getPayConfProperty("epaypp.pkcs8publickey");
			String privatekey=GlobalUtils.getPayConfProperty("epaypp.pkcs8privatekey");
			// 将异步通知中收到的所有参数都存放到map中
			Map<String, String> paramsMap = new TreeMap<String, String>();
			Enumeration<String> names = request.getParameterNames();	        
	        while (names.hasMoreElements()) {
	            String name = names.nextElement();
	            String value = request.getParameter(name);
	            
	            paramsMap.put(name, value);
	        }
	        _log.info("融商异步通知解密前的数据:"+paramsMap);
	      //调用SDK验证签名
	        boolean signVerified = EpayppSignature.rsaCheck(paramsMap, publickey, "UTF-8", SignMethodEnum.RSA);
	        if(signVerified){
	            // 验证签名成功后解密
	            // 1.RSA解密random_key
	            String randomKey = paramsMap.get("random_key");
	            // 解密后的随机密钥
	            randomKey = EpayppEncrypt.decryptContent(randomKey, EncryptTypeEnum.RSA, privatekey, "UTF-8");
	            
	            // 2.AES解密biz_content
	            String bizContent = paramsMap.get("biz_content");
	            bizContent = EpayppEncrypt.decryptContent(bizContent, EncryptTypeEnum.AES, randomKey, "UTF-8");
	            
	            // {"channel":"WECHAT_SCAN","gmt_create":"2017-07-04 15:45:46","gmt_pay":"","out_trade_no":"1499154343825","trade_no":"2017070415450001390009","trade_status":"TRADE_FINISHED"}
	            //JSONObject responseJson = JSON.parseObject(bizContent);
	            Map<String, Object> responseJson=JSON.parseObject(bizContent);
	            //System.out.println(responseJson);
	            _log.info("融商异步通知解密后的数据:"+responseJson);
	            Map<String, String> paramMap = new HashMap<String, String>();
	        	for(Map.Entry<String, Object> entry : responseJson.entrySet()){
	        		paramMap.put(entry.getKey(), String.valueOf(entry.getValue()));           
	            }
	        	String loc_trace_no=paramMap.get("out_trade_no");
	        	Map<String,String> transMap=appLogTransJnlsPayService.getTransJnlsByNo(null, loc_trace_no,null,null);
	            IQuickPayService iQuickPayService=CommonService.getPayServices().get(transMap.get("trf_channel_id"));
	            boolean result=iQuickPayService.noticeOrder(paramMap); 
	           	if(result){  
	           		_log.info("支付成功异步通知管理系统 loc_trace_no=" + paramMap.get("out_trade_no"));
	    			try {
	    				mainBusinessService.asyncNotifyMpos(paramMap.get("out_trade_no"));
	    			} catch (Exception e) {
	    				_log.info("支付成功异步通知管理系统失败");
	    			}
	    			
	    			ResponseDTO responseDto = new ResponseDTO();
         			Map<String, String> dataMap = new HashMap<>();
         			dataMap.put("order_no", transMap.get("order_no"));
         			dataMap.put("channel_trace_no", loc_trace_no);
         			dataMap.put("trans_at", String.valueOf(paramMap.get("amount")));
         			dataMap.put("midfee", "");
         			dataMap.put("costfee", String.valueOf(paramMap.get("charge_amount")));
         			dataMap.put("mchnt_cd", transMap.get("custom_no"));
         			dataMap.put("pay_success_time", StringUtils.isBlank(paramMap.get("gmt_pay"))?"":paramMap.get("gmt_pay"));
         			dataMap.put("trs_stat", CommonService.encapRespCode(paramMap.get("trade_status"), null));// 交易状态
         			dataMap.put("stl_st", "");
         	    	dataMap.put("stl_dt", "");
         	    	dataMap.put("stl_time", "");
         	    	dataMap.put("stl_amt", "");
         	    	String respData = baseInterService.getResponseBizContent(null, dataMap);
         	    	responseDto.setData(respData);
         			mainBusinessService.asyncNotifyDto(transMap.get("dto_bg_url"), loc_trace_no, transMap.get("loc_dt"), responseDto);
	    			
	           	    // 处理成功后，需要返回SUCCESS，通知中心接受到SUCCESS后将不再通知
	           		return "SUCCESS";// 回调成功                
	           	}else{
	           		return "FAIL";// 回调失败
	           	}   
	            
	        }else{
	            //System.out.println("验签不通过");
	            return "FAIL";// 回调失败
	        }
	        	        	        	        
		}
        catch(Exception e){           	 
       	 _log.error("融商异步通知更新发生异常",e);
       	 return "FAIL";// 回调失败
        }  
              
	}
	
	/**
	 * 融商前台回调
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/ePayH5Notice.do")
	public ModelAndView  ePayH5Notice(HttpServletRequest request, HttpServletResponse response) {	
		String result="";
		try{				
			String publickey=GlobalUtils.getPayConfProperty("epaypp.pkcs8publickey");
			String privatekey=GlobalUtils.getPayConfProperty("epaypp.pkcs8privatekey");
			// 将异步通知中收到的所有参数都存放到map中
			Map<String, String> paramsMap = new TreeMap<String, String>();
			Enumeration<String> names = request.getParameterNames();	        
	        while (names.hasMoreElements()) {
	            String name = names.nextElement();
	            String value = request.getParameter(name);
	            
	            paramsMap.put(name, value);
	        }
	        _log.info("融商前台异步通知解密前的数据:"+paramsMap);
	      //调用SDK验证签名
	        boolean signVerified = EpayppSignature.rsaCheck(paramsMap, publickey, "UTF-8", SignMethodEnum.RSA);
	        if(signVerified){
	            // 验证签名成功后解密
	            // 1.RSA解密random_key
	            String randomKey = paramsMap.get("random_key");
	            // 解密后的随机密钥
	            randomKey = EpayppEncrypt.decryptContent(randomKey, EncryptTypeEnum.RSA, privatekey, "UTF-8");
	            
	            // 2.AES解密biz_content
	            String bizContent = paramsMap.get("biz_content");
	            bizContent = EpayppEncrypt.decryptContent(bizContent, EncryptTypeEnum.AES, randomKey, "UTF-8");
	            
	            // {"channel":"WECHAT_SCAN","gmt_create":"2017-07-04 15:45:46","gmt_pay":"","out_trade_no":"1499154343825","trade_no":"2017070415450001390009","trade_status":"TRADE_FINISHED"}
	            //JSONObject responseJson = JSON.parseObject(bizContent);
	            Map<String, Object> responseJson=JSON.parseObject(bizContent);
	            //System.out.println(responseJson);
	            _log.info("融商前台异步通知解密后的数据:"+responseJson);
	            result=String.valueOf(responseJson.get("trade_status"));
	                                   		            
	        }	        	        	        	        
		}
        catch(Exception e){           	 
       	 _log.error("融商前台异步通知更新发生异常",e);            	
        }  
		ModelAndView model=new ModelAndView("/module/pay/epayppPage");		
		model.addObject("result", result);
		return model;      
	}
	
	/**
	 * 易宝支付回调
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/yeePayTransNotice.do")
	public @ResponseBody String yeePayTransNotice(HttpServletRequest request, HttpServletResponse response) {
		try{	
			String hmacKey=GlobalUtils.getPayConfProperty("yeepay.hmacKey");			
			// 将异步通知中收到的所有参数都存放到map中
			Map<String, String> paramsMap = new TreeMap<String, String>();
			Enumeration<String> names = request.getParameterNames();	        
	        while (names.hasMoreElements()) {
	            String name = names.nextElement();
	            String value = request.getParameter(name);
	            
	            paramsMap.put(name, value);
	        }
	        _log.info("易宝收款异步通知的数据:"+paramsMap);
	        
	        StringBuilder hmacStr = new StringBuilder();
	        hmacStr.append(StringUtils.objToString(paramsMap.get("code")))
	        .append(StringUtils.objToString(paramsMap.get("message")))
	        .append(StringUtils.objToString(paramsMap.get("requestId")))
	        .append(StringUtils.objToString(paramsMap.get("customerNumber")))
	        .append(StringUtils.objToString(paramsMap.get("externalld")))
	        .append(StringUtils.objToString(paramsMap.get("createTime")))
	        .append(StringUtils.objToString(paramsMap.get("payTime")))
	        .append(StringUtils.objToString(paramsMap.get("amount")))
	        .append(StringUtils.objToString(paramsMap.get("fee")))
	        .append(StringUtils.objToString(paramsMap.get("status")))
	        .append(StringUtils.objToString(paramsMap.get("busiType")))
	        .append(StringUtils.objToString(paramsMap.get("bankCode")))
	        .append(StringUtils.objToString(paramsMap.get("payerName")))
	        .append(StringUtils.objToString(paramsMap.get("payerPhone")))
	        .append(StringUtils.objToString(paramsMap.get("lastNo")))
	        .append(StringUtils.objToString(paramsMap.get("src")));
	        
	        _log.info("易宝收款异步通知的hmacStr:"+hmacStr.toString());
	        String hmac=paramsMap.get("hmac");
	        //签名
	        String localHmac = Digest.hmacSign(hmacStr.toString(), hmacKey);
	        
	        _log.info("易宝收款异步通知的localHmac:"+localHmac);
	        if(StringUtils.compare(hmac, localHmac)){
	        	
	            paramsMap.put("prefixUrl",request.getRequestURL().substring(0, request.getRequestURL().indexOf(request.getServletPath())));
	        	Map<String, String> transMap = appLogTransJnlsPayService.getTranInfo(paramsMap.get("requestId"));
	        	IQuickPayService iQuickPayService=CommonService.getPayServices().get(transMap.get("trf_channel_id"));
	        	paramsMap.put("noticeFlag", "1");
	        	boolean result=iQuickPayService.noticeOrder(paramsMap); 
	           	if(result){
	           		_log.info("支付成功异步通知管理系统 loc_trace_no=" + paramsMap.get("requestId"));
	    			try {
	    				mainBusinessService.asyncNotifyMpos(paramsMap.get("requestId"));
	    			} catch (Exception e) {
	    				_log.info("支付成功异步通知管理系统失败");
	    			}
	    			
	    			ResponseDTO responseDto = new ResponseDTO();
         			Map<String, String> dataMap = new HashMap<>();
         			dataMap.put("order_no", transMap.get("order_no"));
         			dataMap.put("channel_trace_no", paramsMap.get("requestId"));
         			dataMap.put("trans_at", String.valueOf(paramsMap.get("amount")));
         			dataMap.put("midfee", "");
         			dataMap.put("costfee", "");
         			dataMap.put("mchnt_cd", transMap.get("custom_no"));
         			dataMap.put("pay_success_time", StringUtils.isBlank(paramsMap.get("payTime"))?"":paramsMap.get("payTime"));
         			dataMap.put("trs_stat", CommonService.encapRespCode(paramsMap.get("status"), null));
         			dataMap.put("stl_st", "");
         	    	dataMap.put("stl_dt", "");
         	    	dataMap.put("stl_time", "");
         	    	String respData = baseInterService.getResponseBizContent(null, dataMap);
         	    	responseDto.setData(respData);
         			mainBusinessService.asyncNotifyDto(transMap.get("dto_bg_url"), paramsMap.get("requestId"), transMap.get("loc_dt"), responseDto);
	    			
	           	    // 处理成功后，需要返回SUCCESS，通知中心接受到SUCCESS后将不再通知
	           		return "SUCCESS";// 回调成功                
	           	}else{
	           		return "FAIL";// 回调失败
	           	}  	        	
	        }else{	            
	            _log.info("易宝收款异步通知验签不通过");
	            return "FAIL";// 回调失败
	        }	      
	        	        	        	        
		}
        catch(Exception e){           	 
       	 _log.error("易宝收款异步通知更新发生异常",e);
       	 return "FAIL";// 回调失败
        }  
              
	}
	
	/**
	 * 易宝结算回调
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/yeePayWithdrawNotice.do")
	public @ResponseBody String yeePayWithdrawNotice(HttpServletRequest request, HttpServletResponse response) {
		try{
			String hmacKey=GlobalUtils.getPayConfProperty("yeepay.hmacKey");			
			// 将异步通知中收到的所有参数都存放到map中
			Map<String, String> paramsMap = new TreeMap<String, String>();
			Enumeration<String> names = request.getParameterNames();	        
	        while (names.hasMoreElements()) {
	            String name = names.nextElement();
	            String value = request.getParameter(name);
	            
	            paramsMap.put(name, value);
	        }
	        _log.info("易宝结算异步通知的数据:"+paramsMap);
	        
	        StringBuilder hmacStr = new StringBuilder();
	        hmacStr.append(StringUtils.objToString(paramsMap.get("mainCustomerNumber")))
	        .append(StringUtils.objToString(paramsMap.get("customerNumber")))
	        .append(StringUtils.objToString(paramsMap.get("externalNo")))
	        .append(StringUtils.objToString(paramsMap.get("serialNo")))
	        .append(StringUtils.objToString(paramsMap.get("transferStatus")))
	        .append(StringUtils.objToString(paramsMap.get("requestTime")))
	        .append(StringUtils.objToString(paramsMap.get("handleTime")))
	        .append(StringUtils.objToString(paramsMap.get("transferWay")))
	        .append(StringUtils.objToString(paramsMap.get("receiver")))
	        .append(StringUtils.objToString(paramsMap.get("receiverBankCardNo")))
	        .append(StringUtils.objToString(paramsMap.get("receiverBank")))
	        .append(StringUtils.objToString(paramsMap.get("amount")))
	        .append(StringUtils.objToString(paramsMap.get("fee")))
	        .append(StringUtils.objToString(paramsMap.get("basicFee")))
	        .append(StringUtils.objToString(paramsMap.get("exTargetFee")))
	        .append(StringUtils.objToString(paramsMap.get("actualAmount")))
	        .append(StringUtils.objToString(paramsMap.get("failReason")));
	        _log.info("易宝结算异步通知的hmacStr:"+hmacStr.toString());
	        String hmac=paramsMap.get("hmac");
	        //签名
	        String localHmac = Digest.hmacSign(hmacStr.toString(), hmacKey);
	        
	        _log.info("易宝结算异步通知的localHmac:"+localHmac);
	        if(StringUtils.compare(hmac, localHmac)){
	        	Map<String, String> infoMap = appLogTransJnlsPayService.selectLogChannelStl(paramsMap.get("externalNo"));	        	
	        	IQuickPayService iQuickPayService=CommonService.getPayServices().get(infoMap.get("trf_channel_id"));
	        	paramsMap.put("noticeFlag", "2");
	        	boolean result=iQuickPayService.noticeOrder(paramsMap); 
	           	if(result){  
	           	// 处理成功后，需要返回SUCCESS，通知中心接受到SUCCESS后将不再通知
	           		return "SUCCESS";// 回调成功                
	           	}else{
	           		return "FAIL";// 回调失败
	           	}  
	        	
	        }else{
	            
	            _log.info("易宝结算异步通知验签不通过");
	            return "FAIL";// 回调失败
	        }	      
	        	        	        	        
		}
        catch(Exception e){           	 
       	 _log.error("易宝结算异步通知更新发生异常",e);
       	 return "FAIL";// 回调失败
        }  
              
	}
	
	/**
	 * 易宝前台回调
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/yeePayPageNotice.do")
	public ModelAndView yeePayPageNotice(HttpServletRequest request, HttpServletResponse response) throws Exception{		
		Map<String, String> paramsMap = new TreeMap<String, String>();
		Enumeration<String> names = request.getParameterNames();	        
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            String value = request.getParameter(name);
            
            paramsMap.put(name, value);
        }
        _log.info("易宝前台异步通知的数据:"+paramsMap);
        return new ModelAndView("redirect:/module/pay/yeePayPage.html");
                               
	}
			
	
	/**
	 * 欣客异步通知
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/xinKeTransNotice.do")
	public @ResponseBody String xinKeTransNotice(HttpServletRequest request, HttpServletResponse response) {
		try{			
			// 将异步通知中收到的所有参数都存放到map中
			Map<String, String> paramsMap = new TreeMap<String, String>();
			Enumeration<String> names = request.getParameterNames();	        
	        while (names.hasMoreElements()) {
	            String name = names.nextElement();
	            String value = request.getParameter(name);
	            
	            paramsMap.put(name, value);
	        }
	        _log.info("欣客异步通知的数据:"+paramsMap);	        
	        	        	        	        	       	
    		Map<String, String> transMap = appLogTransJnlsPayService.getTranInfo(String.valueOf(paramsMap.get("orderNo")));
    		IQuickPayService iQuickPayService=CommonService.getPayServices().get(transMap.get("trf_channel_id"));
    		boolean result=iQuickPayService.noticeOrder(paramsMap); 
           	if(result){
           		_log.info("支付成功异步通知管理系统 loc_trace_no=" + paramsMap.get("orderNo"));
    			try {
    				mainBusinessService.asyncNotifyMpos(paramsMap.get("orderNo"));
    			} catch (Exception e) {
    				_log.info("支付成功异步通知管理系统失败");
    			}
    			
    			ResponseDTO responseDto = new ResponseDTO();
     			Map<String, String> dataMap = new HashMap<>();
     			String transDate=StringUtils.isBlank(paramsMap.get("transDate"))?"":paramsMap.get("transDate");
     			String transTime=StringUtils.isBlank(paramsMap.get("transTime"))?"":paramsMap.get("transTime");
     			dataMap.put("order_no", transMap.get("order_no"));
     			dataMap.put("channel_trace_no", paramsMap.get("orderNo"));
     			dataMap.put("trans_at", String.valueOf(paramsMap.get("transAmt")));
     			dataMap.put("midfee", "");
     			dataMap.put("costfee", "");
     			dataMap.put("mchnt_cd", transMap.get("custom_no"));
     			dataMap.put("pay_success_time", transDate + transTime);
     			dataMap.put("trs_stat", CommonService.encapRespCode(paramsMap.get("transStatus"), null));// 交易状态
     			dataMap.put("stl_st", "");
     	    	dataMap.put("stl_dt", "");
     	    	dataMap.put("stl_time", "");
     	    	dataMap.put("stl_amt", "");
     	    	String respData = baseInterService.getResponseBizContent(null, dataMap);
     	    	responseDto.setData(respData);
     			mainBusinessService.asyncNotifyDto(transMap.get("dto_bg_url"), paramsMap.get("orderNo"), transMap.get("loc_dt"), responseDto);
    			
           	    // 处理成功后，需要返回SUCCESS，通知中心接受到SUCCESS后将不再通知
           		return "SUCCESS";// 回调成功                
           	}else{
           		return "FAIL";// 回调失败
           	} 	       		        		        	 	        		        	      
	        	        	        	        
		}
        catch(Exception e){           	 
       	 _log.error("欣客异步通知更新发生异常",e);
       	 return "FAIL";// 回调失败
        }  
              
	}
	
	/**
	 * 欣客前台回调
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/xinKePageNotice.do")
	public ModelAndView xinKePageNotice(HttpServletRequest request, HttpServletResponse response) throws Exception{		
		Map<String, String> paramsMap = new TreeMap<String, String>();
		Enumeration<String> names = request.getParameterNames();	        
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            String value = request.getParameter(name);
            
            paramsMap.put(name, value);
        }
        _log.info("欣客前台异步通知的数据:"+paramsMap);
        return new ModelAndView("redirect:/module/pay/yeePayPage.html");
                               
	}
	
	/**
	 * 上海汇宜发送短信验证码
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/sendVerifyCode.do")
	public @ResponseBody Map sendVerifyCode(HttpServletRequest request, HttpServletResponse response, GpsEntity gpsEntity,
			String random_number, String custom_no, String loc_trace_no, String phone, String login_id) {
		StringBuilder builder = new StringBuilder().append(StringUtils.objToString(gpsEntity.getSerial_number()))
				.append(StringUtils.objToString(custom_no)).append(StringUtils.objToString(loc_trace_no))
				.append(StringUtils.objToString(phone));
		return payService.sendVerifyCode(request, response, gpsEntity, random_number, custom_no, loc_trace_no, phone,
				login_id, builder.toString());
	}
	
	/**
	 * 上海汇宜异步回调
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/huiePayNotice.do")
	public @ResponseBody String huiePayNotice(HttpServletRequest request, HttpServletResponse response) {
		DataMessage dataMessage = new DataMessage(GlobalUtils.getPayConfProperty("huiepay.pay.version"), GlobalUtils.getPayConfProperty("huiepay.pay.encoding"), "01");
		String privateKeyPath = GlobalUtils.getPayConfProperty("huiepay.pay.privateKeyPath");
		String publicKeyPath = GlobalUtils.getPayConfProperty("huiepay.pay.publicKeyPath");
		String resultVal = "";
		
		Map<String,Object> kv =new HashMap<String, Object>();
		kv.put("tran_cd", GlobalUtils.getPayConfProperty("tran_cd"));  //交易类型
		kv.put("chn_ins_id_cd", GlobalUtils.getPayConfProperty("chn_ins_id_cd"));  //密钥机构号
		kv.put("prod_cd", GlobalUtils.getPayConfProperty("prod_cd")); //产品编码T1:1140  T0:1171
		kv.put("biz_cd", GlobalUtils.getPayConfProperty("biz_cd"));  //0000026业务编码
		kv.put("ins_id_cd", GlobalUtils.getPayConfProperty("ins_id_cd"));  //机构代码
		kv.put("mcht_cd", GlobalUtils.getPayConfProperty("mcht_cd"));  //商户号
		kv.put("order_id", "");  //商户订单号
		kv.put("sys_order_id", "");  //系统订单号
		kv.put("resp_cd", "");  //响应码
		kv.put("resp_msg", "");//响应信息
		
   		RSAUtils rsaUtils = new RSAUtils();
	    rsaUtils.initKey(privateKeyPath, publicKeyPath);
		
		try{			
			// 将异步通知中收到的所有参数都存放到map中
			Map<String, String> paramsMap = new TreeMap<String, String>();
			Enumeration<String> names = request.getParameterNames();	        
	        while (names.hasMoreElements()) {
	            String name = names.nextElement();
	            String value = request.getParameter(name);
	            
	            paramsMap.put(name, value);
	        }
	        _log.info("上海汇宜异步通知的数据:"+paramsMap);
	        
	        
	        /*Map<String, Object> paramsMap = new TreeMap<String, Object>();
	        String requestMessage = request.getParameter("");	    
	        DataMessage respData = (DataMessage)JsonUtil.fromJsonToObj(requestMessage, DataMessage.class);
	        String respMsgBody = respData.getMsg_body();
	        String respSignStr = respData.getSignature();
	        if (!rsaUtils.verify(respMsgBody, respSignStr, GlobalUtils.getPayConfProperty("huiepay.pay.encoding"))) {
	        	resultVal = toJsonByObj(dataMessage, kv, rsaUtils);
	        	return resultVal;
	        }else{
	        	paramsMap = (Map<String, Object>) JsonUtil.fromJsonToObj(requestMessage, Map.class);
	        }
	        _log.info("上海汇宜异步通知的数据:"+paramsMap);*/
	        
        	String loc_trace_no=paramsMap.get("order_id");
       		kv.put("order_id", loc_trace_no);  //商户订单号
    		kv.put("sys_order_id", paramsMap.get("sys_order_id"));  //系统订单号
	        
        	Map<String,String> transMap=appLogTransJnlsPayService.getTransJnlsByNo(null, loc_trace_no,null,null);
            IQuickPayService iQuickPayService=CommonService.getPayServices().get(transMap.get("trf_channel_id"));
            boolean result=iQuickPayService.noticeOrder(paramsMap); 
           	if(result){
        		kv.put("resp_cd", SystemConstant.RSPCODE_SUCCESS);  //响应码
        		kv.put("resp_msg", SystemConstant.RSPCODE_SUCCESS_MSG);//响应信息
        	    resultVal = toJsonByObj(dataMessage, kv, rsaUtils);
           		
           		_log.info("支付成功异步通知管理系统 loc_trace_no=" + paramsMap.get("order_id"));
    			try {
    				mainBusinessService.asyncNotifyMpos(paramsMap.get("order_id"));
    			} catch (Exception e) {
    				_log.info("支付成功异步通知管理系统失败");
    			}
    			
    			ResponseDTO responseDto = new ResponseDTO();
     			Map<String, String> dataMap = new HashMap<>();
     			dataMap.put("order_no", transMap.get("order_no"));
     			dataMap.put("channel_trace_no", paramsMap.get("order_id"));
     			dataMap.put("trans_at", String.valueOf(paramsMap.get("tran_amt")));
     			dataMap.put("midfee", "");
     			dataMap.put("costfee", "");
     			dataMap.put("mchnt_cd", transMap.get("custom_no"));
     			dataMap.put("pay_success_time", StringUtils.isBlank(paramsMap.get("tran_dt_tm"))?"":paramsMap.get("tran_dt_tm"));
     			dataMap.put("trs_stat", CommonService.encapRespCode(paramsMap.get("trade_status"), null));
     			dataMap.put("stl_st", "");
     	    	dataMap.put("stl_dt", paramsMap.get("sett_dt"));
     	    	dataMap.put("stl_time", "");
     	    	String respData = baseInterService.getResponseBizContent(null, dataMap);
     	    	responseDto.setData(respData);
     			mainBusinessService.asyncNotifyDto(transMap.get("dto_bg_url"), paramsMap.get("requestId"), transMap.get("loc_dt"), responseDto);
    			
           		return resultVal;// 回调成功                
           	}else{
           		kv.put("resp_cd", SystemConstant.RSPCODE_ERROR);  //响应码
     		    kv.put("resp_msg", SystemConstant.RSPCODE_ERROR_MSG);//响应信息
           		resultVal = toJsonByObj(dataMessage, kv, rsaUtils);
           		return resultVal;// 回调失败
           	}   
		}
        catch(Exception e){           	 
       	    _log.error("上海汇宜异步通知更新发生异常",e);
       	    kv.put("resp_cd", SystemConstant.RSPCODE_ERROR);  //响应码
 		    kv.put("resp_msg", SystemConstant.RSPCODE_ERROR_MSG);//响应信息
       	    resultVal = toJsonByObj(dataMessage, kv, rsaUtils);
       	    return resultVal;// 回调失败
        }  
	}

	private String toJsonByObj(DataMessage dataMessage, Map<String, Object> kv,
			RSAUtils rsaUtils) {
		String resultVal;
		String charset0 = dataMessage.getEncoding();
		String signStr = rsaUtils.sign(JsonUtil.toJsonByObj(kv), charset0);
		dataMessage.setSignature(signStr);
		dataMessage.setMsg_body(JsonUtil.toJsonByObj(kv));
		resultVal = JsonUtil.toJsonByObj(dataMessage);
		return resultVal;
	}
}
